﻿
namespace TransportAnalizer_2._0.Model
{
    using System;
    using System.Collections.Generic;
    using System.Linq;

    /// <summary>
    /// Encapsulates business rules when accessing the data layer.
    /// </summary>
    public sealed class NodeBusinessContext : IDisposable, TransportAnalizer_2._0.Model.INodeBusinessContext
    {
        private TransportAnalizerModelContext context;
        private bool disposed;

        /// <summary>
        /// Initializes a new instance of the <see cref="NodeBusinessContext"/> class.
        /// </summary>
        public NodeBusinessContext()
        {
            context = new TransportAnalizerModelContext();
        }

        /// <summary>
        /// Gets and Sets the underlying <see cref="DataContext"/>.
        /// </summary>
        public TransportAnalizerModelContext DataContext
        {
            get { return context; }
            set { context = value; }
        }

        #region NodeBusinessContext
        /// <summary>
        /// Adds a new node entity to the data store.
        /// </summary>
        /// <param name="node"></param>
        public void CreateNode(Node node)
        {
            Check.RequireObjectNotNull(node.Location);
            if (context.NodeTypeSet.Count() == 0)
            {
                throw new ArgumentException();
            }

            node.NodeType = context.NodeTypeSet.OrderBy(p => p.Id).ToArray()[0];
           
            context.NodeSet.Add(node);
            context.SaveChanges();
        }

        /// <summary>
        /// Updates the specified node by applying the values passed in over the existing values from the data store.
        /// </summary>
        /// <param name="node">The node entity containing the new values to persist.</param>
        public void UpdateNode(Node node)
        {
            var entity = context.NodeSet.Find(node.Id);

            if (entity == null)
            {
                throw new NotImplementedException("Handle appropriately for your API design.");
            }

            context.Entry(node).CurrentValues.SetValues(node);
            context.SaveChanges();
        }

        /// <summary>
        /// Deletes the specified node.
        /// </summary>
        /// <param name="node">The node to delete.</param>
        public void DeleteNode(Node node)
        {
            context.NodeSet.Remove(node);
            context.SaveChanges();
        }


        /// <summary>
        /// Gets a collection of Nodes.
        /// </summary>
        /// <returns>Returns a collection of <see cref="Node"/> entities ordered by primary key.</returns>
        public ICollection<Node> GetNodeList()
        {
            return context.NodeSet.OrderBy(p => p.Id).ToArray();
        }

        #endregion NodeBusinessContext


        #region IDisposable Members

        /// <summary>
        /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
        /// </summary>
        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }

        private void Dispose(bool disposing)
        {
            if (disposed || !disposing)
                return;

            if (context != null)
                context.Dispose();

            disposed = true;
        }

        #endregion
    }

}
